package com.yuyou.fn.electronicinvoice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.rocketmq.Consumer;
import com.yuyou.fn.common.service.IEmailService;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.CourseOrder;
import com.yuyou.fn.educational.entity.StudentReg;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.educational.service.ICourseOrderService;
import com.yuyou.fn.educational.service.IStudentRegService;
import com.yuyou.fn.electronicinvoice.entity.FinanceSubject;
import com.yuyou.fn.electronicinvoice.entity.FinanceSubjectCampus;
import com.yuyou.fn.electronicinvoice.entity.Invoice;
import com.yuyou.fn.electronicinvoice.entity.RecordTempInvoice;
import com.yuyou.fn.electronicinvoice.mapper.InvoiceMapper;
import com.yuyou.fn.electronicinvoice.service.*;
import com.yuyou.fn.electronicinvoice.vo.*;
import com.yuyou.fn.electronicinvoice.webservice.IEliWebServiceStub;
import org.apache.axis2.AxisFault;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.*;

/**
 * Invoice 表数据服务层接口实现类
 */
@Service
public class InvoiceServiceImpl extends SuperServiceImpl<InvoiceMapper, Invoice, Long> implements IInvoiceService {
    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IFinanceSubjectService financeSubjectService;

    @Resource
    private IElectronicInvoiceService electronicInvoiceService;

    @Resource
    private ISiteConfigService siteConfigService;

    @Resource
    private Consumer consumer;

    @Resource
    private IEmailService emailService;

    @Resource
    private IRecordTempInvoiceService recordTempInvoiceService;

    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Resource
    private ICourseOrderService courseOrderService;

    @Resource
    private IFinanceSubjectCampusService financeSubjectCampusService;

    private final static Logger log  = LoggerFactory.getLogger(InvoiceServiceImpl.class);

    @PostConstruct
    public void init() {

    }


    @Override
    public Page<StudentClassInvoiceVo> findStudentClassInvoicePage(StudentInvoiceQueryVo studentInvoiceQueryVo, int pageNo, int pageSize) {
        Example<Invoice> example=Invoice.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,studentInvoiceQueryVo);
        Page<Invoice> invoicePage=this.findPageByExample(example,pageNo,pageSize);
        Page<StudentClassInvoiceVo> studentClassInvoiceVoPage= Utils.newPage(invoicePage);
        if (invoicePage.getRecords()!=null){
            List<Invoice> invoiceList=invoicePage.getRecords();

            List<StudentClassInvoiceVo> studentClassInvoiceVoList=new ArrayList<>(invoiceList.size());
            for (Invoice invoice:invoiceList){

                StudentClassInvoiceVo studentClassInvoiceVo=new StudentClassInvoiceVo();

                studentClassInvoiceVo.setInvoiceId(invoice.getInvoiceId());
                studentClassInvoiceVo.setTaxTotalAmount(invoice.getTaxTotalAmount());
                studentClassInvoiceVo.setInvoiceType(invoice.getInvoiceType());
                studentClassInvoiceVo.setStudentId(invoice.getBuyerId());
                studentClassInvoiceVo.setStudentName(invoice.getBuyerName());
                studentClassInvoiceVo.setStudentPhoneNo(invoice.getBuyerPhone());
                studentClassInvoiceVo.setOperatorId(invoice.getOperatorId());
                studentClassInvoiceVo.setOperatorName(invoice.getOperatorName());
                studentClassInvoiceVo.setCreateTime(invoice.getCreateTime());
                studentClassInvoiceVo.setUpdateTime(invoice.getUpdateTime());
                studentClassInvoiceVoList.add(studentClassInvoiceVo);
            }
            studentClassInvoiceVoPage.setRecords(studentClassInvoiceVoList);

        }
        return studentClassInvoiceVoPage;
    }
    @Override
    public SXSSFWorkbook exportStudentClassInvoice(StudentInvoiceQueryVo studentInvoiceQueryVo){
        return  studentClassInvoice2Excel(this.findStudentClassInvoicePage(studentInvoiceQueryVo,1,50000).getRecords());
    }

    @Override
    public List<Invoice> findByOrderIdsGoodTypeInvoiceTypeStatus(List<Long> orderIds, int goodType, int invoiceType, int status) {
        Example<Invoice> example=Invoice.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("orderId",orderIds);
        criteria.andEqualTo("goodType",goodType);
        criteria.andEqualTo("invoiceType",invoiceType);
        criteria.andEqualTo("status",status);
        return this.findListByExample(example);
    }

    public static SXSSFWorkbook studentClassInvoice2Excel(List<StudentClassInvoiceVo> studentClassInvoiceVoList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("发票使用情况");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"发票流水号","价税合计金额","开票类型","学生姓名","学生电话","操作人","操作时间"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        if (studentClassInvoiceVoList!=null){
            for (StudentClassInvoiceVo studentClassInvoiceVo:studentClassInvoiceVoList){
                int cellNum = 0;
                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(studentClassInvoiceVo.getInvoiceId().toString());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(studentClassInvoiceVo.getTaxTotalAmount()==null?0d:studentClassInvoiceVo.getTaxTotalAmount().doubleValue());

                cell = row.createCell(cellNum++);
            /*1正票、2红票*/
                cell.setCellValue(studentClassInvoiceVo.getInvoiceType()==1?"正票":"红冲");

                cell = row.createCell(cellNum++);
                cell.setCellValue(studentClassInvoiceVo.getStudentName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(studentClassInvoiceVo.getStudentPhoneNo()));




                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(studentClassInvoiceVo.getOperatorName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(Utils.formatDate(studentClassInvoiceVo.getUpdateTime(),"yyyy-MM-dd HH:mm:ss"));

            }
        }

        return excel;
    }


    @Override
    public List<Invoice> findInvoiceByOrderId(long orderId) {
        Example<Invoice> example = Invoice.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", orderId);
        example.orderBy("createTime").desc();
        example.orderBy("invoiceType");
        return this.findListByExample(example);
    }

    @Override
    public Invoice openRegInvoice(Long regId, Integer invoiceType) {
        StudentReg studentReg = studentRegService.findById(regId);
        List<Invoice> invoiceList=this.findByOrderIdsGoodTypeInvoiceTypeStatus(Arrays.asList(studentReg.getCourseOrderId()),2,1,1);
        if (!Utils.isEmpty(invoiceList)){
            throw new BusException("该班级已经开票，请前往“订单信息-发票管理”查看！");
        }
        if (studentReg.getRegStatus() != 0 && studentReg.getChargingStatus() != 2) {
            throw new BusException("必须缴费完成才能开票");
        }
        CourseClass courseClass = courseClassService.findById(studentReg.getClassId());
        if (courseClass.getCampusId() == null) {
            throw new BusException("该校区尚未设置财务主体，须完善之后才能开票!");
        }

        FinanceSubject financeSubject = financeSubjectService.findByCampusIdAndSubjectStatus(courseClass.getCampusId().toString(), 1);
        if (financeSubject == null) {
            throw new BusException("该校区尚未设置财务主体，须完善之后才能开票!");
        }
        BigDecimal amount = studentReg.getPayAmount().subtract(studentReg.getRefundAmount());
        if (invoiceType == 2) {
            amount = amount.multiply(new BigDecimal(-1));
        }
        RecordTempInvoice recordTempInvoice=recordTempInvoiceService.findOrCreateByObjectId(regId,1,1,"regId");
        Invoice invoice = new Invoice();
        invoice.setInvoiceId(recordTempInvoice.getRecordTempInvoiceId());
        invoice.setOrderId(regId);
        invoice.setGoodId(studentReg.getClassId());
        invoice.setGoodName(studentReg.getClassName());
        invoice.setGoodType(1);//课程
        invoice.setBuyerId(studentReg.getStudentId());
        invoice.setBuyerName(studentReg.getStudentName());
        invoice.setInvoiceProject(financeSubject.getInvoiceProject());
        invoice.setTaxTotalAmount(amount);
        invoice.setInvoiceType(invoiceType);
        invoice.setInvoiceMember(financeSubject.getInvoiceMember());
        invoice.setFinanceSubjectId(financeSubject.getFinanceSubjectId());
        invoice.setCreateTime(TimeUtils.now());
        invoice.setUpdateTime(TimeUtils.now());

        return invoice;
    }

    @Override
    public Invoice openOrderInvoice(long courseOrderId, Integer invoiceType) {
        CourseOrder courseOrder=courseOrderService.findById(courseOrderId);
        if (courseOrder.getChargingStatus()!=2){
            throw new BusException("必须缴费完成才能开票");
        }
        BigDecimal totalAmount=BigDecimal.ZERO;
        List<StudentReg> studentRegList=studentRegService.findByCourseOrderIds(Arrays.asList(courseOrderId));
        for (StudentReg studentReg:studentRegList){
            totalAmount=totalAmount.add(studentReg.getPayAmount()).subtract(studentReg.getRefundAmount());
        }
        List<Long> regIds = BeanUtils.toList(studentRegList, "regId");
        List<Invoice> invoiceList=this.findByOrderIdsGoodTypeInvoiceTypeStatus(regIds,1,1,1);
        if (invoiceList.size()>0){
            throw new BusException("该订单已有班级开过发票，请前往“在读班级-发票管理”操作！");
        }

        if (totalAmount.equals(BigDecimal.ZERO)){
            throw new BusException("开票金额必须大于0");
        }
        List<Long> classIds = BeanUtils.toList(studentRegList, "classId");
        List<CourseClass> courseClassList=courseClassService.findByIds(classIds);
        List<Long> campusIds=new ArrayList<>(courseClassList.size());
        for (CourseClass courseClass:courseClassList){
            if (courseClass.getCampusId()==null){
                throw new BusException("该订单存在班级尚未设置财务主体，须完善之后才能开票!");
            }
            campusIds.add(courseClass.getCampusId());
        }
        List<FinanceSubjectCampus> financeSubjectCampusList=financeSubjectCampusService.findByCampusIds(campusIds,1);
        List<Long> financeSubjectIds = Utils.removeDuplicate(BeanUtils.toList(financeSubjectCampusList, "financeSubjectId"));
        if (financeSubjectIds.size()>1){
            throw new BusException("该订单涉及的班级有多个财务主体，请分开开票");
        }
        if (financeSubjectIds.size()==0){
            throw new BusException("该订单涉及的班级尚未设置财务主体，须完善之后才能开票!");
        }
        Long financeSubjectId=financeSubjectIds.get(0);
        FinanceSubject financeSubject=financeSubjectService.findById(financeSubjectId);

        RecordTempInvoice recordTempInvoice=recordTempInvoiceService.findOrCreateByObjectId(courseOrderId,1,1,"courseOrderId");
        Invoice invoice = new Invoice();
        invoice.setInvoiceId(recordTempInvoice.getRecordTempInvoiceId());
        invoice.setOrderId(courseOrderId);
        invoice.setGoodId(courseOrderId);
        invoice.setGoodName("课程订单");
        invoice.setGoodType(2);//课程订单
        invoice.setBuyerId(courseOrder.getStudentId());
        invoice.setBuyerName(courseOrder.getStudentName());
        invoice.setInvoiceProject(financeSubject.getInvoiceProject());
        invoice.setTaxTotalAmount(totalAmount);
        invoice.setInvoiceType(invoiceType);
        invoice.setInvoiceMember(financeSubject.getInvoiceMember());
        invoice.setFinanceSubjectId(financeSubject.getFinanceSubjectId());
        invoice.setCreateTime(TimeUtils.now());
        invoice.setUpdateTime(TimeUtils.now());

        return invoice;
    }


    @Override
    public InvoiceSaveVo openInvoice(long orderId, Integer invoiceType, String orderType) {
        InvoiceSaveVo invoiceSaveVo=new InvoiceSaveVo();
        if ("regId".equals(orderType)){
            Invoice invoice=this.openRegInvoice(orderId,invoiceType);
            BeanUtils.copyProperties(invoiceSaveVo,invoice);
        }else if ("courseOrderId".equals(orderType)){
            Invoice invoice=this.openOrderInvoice(orderId,invoiceType);
            BeanUtils.copyProperties(invoiceSaveVo,invoice);
        }
        invoiceSaveVo.setInvoiceType(1);
        invoiceSaveVo.setOperationCode(10);
        return invoiceSaveVo;
    }

    @Override
    public InvoiceSaveVo rushInvoice(long invoiceId) {
        Invoice invoice=this.findById(invoiceId);
        InvoiceSaveVo invoiceSaveVo=new InvoiceSaveVo();
        BeanUtils.copyProperties(invoiceSaveVo,invoice);
        invoiceSaveVo.setRushInvoiceId(invoice.getInvoiceId());
        invoiceSaveVo.setInvoiceType(2);
        invoiceSaveVo.setOperationCode(21);
        RecordTempInvoice recordTempInvoice=recordTempInvoiceService.findOrCreateByObjectId(invoiceId,1,2,"invoiceId");
        invoiceSaveVo.setInvoiceId(recordTempInvoice.getRecordTempInvoiceId());
        return invoiceSaveVo;
    }

    @Override
    public Invoice findByOrderIdAndStatus(Long orderId,Integer invoiceType, Integer status) {
        Example<Invoice> example=Invoice.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("orderId",orderId);
        criteria.andEqualTo("status",status);
        criteria.andEqualTo("invoiceType",invoiceType);
        return this.findOneByExample(example);
    }

    @Override
    public void checkHaveOpen(Long orderId, Integer invoiceType, Integer status) {
        Invoice invoice=this.findByOrderIdAndStatus(orderId,invoiceType,status);
        if (invoice!=null){
            throw new BusException("该信息已经开过发票，如有误请红冲后再开");
        }
    }

    @Override
    public Invoice saveOrRushInvoice(InvoiceSaveVo invoiceSaveVo) throws org.apache.axis2.AxisFault, RemoteException {
        if (invoiceSaveVo.getFinanceSubjectId()==null || invoiceSaveVo.getTaxTotalAmount()==null || invoiceSaveVo.getOrderId()==null ){
            throw new  BusException("缺乏必要参数");
        }
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别，开启新事务
        TransactionStatus status = dataSourceTransactionManager.getTransaction(def); // 获得事务状态

        try {
            InvoiceParamter invoiceParamter = new InvoiceParamter();
            //StudentReg studentReg = studentRegService.findById(invoiceSaveVo.getOrderId());

            //CourseClass courseClass = courseClassService.findById(studentReg.getClassId());

            FinanceSubject financeSubject = financeSubjectService.findById(invoiceSaveVo.getFinanceSubjectId());
            if (financeSubject == null) {
                throw new BusException("该校区尚未设置财务主体，须完善之后才能开票!");
            }
            BigDecimal amount = invoiceSaveVo.getTaxTotalAmount();// studentReg.getPayAmount().subtract(studentReg.getRefundAmount());
            Double projectNum = 1d;
        /*红冲的话，金额为负数，取原来开票的信息金额*/
            if (invoiceSaveVo.getInvoiceType() == 2) {
                if (invoiceSaveVo.getRushInvoiceId()==null){
                    throw new BusException("开红票请传入要冲掉的票");
                }
                Invoice orginInvoice = this.findById(invoiceSaveVo.getRushInvoiceId());
                if (orginInvoice.getStatus()!=1){
                    throw new BusException("该发票已被红冲");
                }
                if (orginInvoice != null) {
                    invoiceParamter.setOriginalInvoiceCode(orginInvoice.getInvoiceCode());
                    invoiceParamter.setOriginalInvoiceNumber(orginInvoice.getInvoiceNumber());
                }
                Invoice update = new Invoice();
                update.setInvoiceId(orginInvoice.getInvoiceId());
                update.setUpdateTime(TimeUtils.now());
                update.setStatus(0);
                invoiceParamter.setRemark("对应正数发票代码:"+orginInvoice.getInvoiceCode()+"号码:"+orginInvoice.getInvoiceNumber());
                this.updateSelectiveById(update);
                amount = orginInvoice.getTaxTotalAmount().multiply(new BigDecimal(-1));
                projectNum = -1d;
            }else {
         /*       if (studentReg.getRegStatus() != 0 && studentReg.getChargingStatus() != 2) {
                    throw new BusException("必须缴费完成才能开票");
                }*/
                this.checkHaveOpen(invoiceSaveVo.getOrderId(),invoiceSaveVo.getInvoiceType(),1);
            }

            invoiceSaveVo.setTaxTotalAmount(amount.abs());

            invoiceParamter.setRemark(invoiceSaveVo.getRemark());
            invoiceParamter.setInvoiceId(invoiceSaveVo.getInvoiceId().toString());
            invoiceParamter.setBuyerEmail(invoiceSaveVo.getBuyerEmail());
            invoiceParamter.setBuyerPhone(invoiceSaveVo.getBuyerPhone());
            invoiceParamter.setBuyerName(invoiceSaveVo.getBuyerName());
            invoiceParamter.setOrderId(invoiceSaveVo.getOrderId().toString());
            invoiceParamter.setTaxTotalAmount(amount.doubleValue());
            invoiceParamter.setInvoiceType(invoiceSaveVo.getInvoiceType().toString());
            invoiceParamter.setOperationCode(invoiceSaveVo.getOperationCode().toString());

            String taxClassificationCode=siteConfigService.getConfigValueFromCache("tax_class_ification_code");
            invoiceParamter.setTaxClassificationCode(taxClassificationCode);
            invoiceParamter.setInvoicerIdentificationNo(financeSubject.getInvoicerIdentificationNo());
            invoiceParamter.setInvoicerIdentificationName(financeSubject.getInvoicerIdentificationName());
            invoiceParamter.setInvoicerElectronicFile(financeSubject.getInvoicerElectronicFile());
            invoiceParamter.setTaxCode(financeSubject.getTaxCode());
            invoiceParamter.setIssueSign(financeSubject.getIssueSign().toString());
            invoiceParamter.setInvoiceProject(financeSubject.getInvoiceProject());
            invoiceParamter.setSaleNo(financeSubject.getSaleNo());
            invoiceParamter.setSaleName(financeSubject.getSaleName());
            invoiceParamter.setSaleAddress(financeSubject.getSaleAddress());
            invoiceParamter.setSalePhone(financeSubject.getSalePhone());
            invoiceParamter.setSaleBankName(financeSubject.getSaleBankName());
            invoiceParamter.setIndustryCode(financeSubject.getIndustryCode());
            invoiceParamter.setIndustryName(financeSubject.getIndustryName());
            invoiceParamter.setInvoiceMember(financeSubject.getInvoiceMember());

            InvoiceDetailParamter invoiceDetailParamter = new InvoiceDetailParamter();
            invoiceDetailParamter.setTaxRate(financeSubject.getTaxRate());
            invoiceDetailParamter.setGoodCategoryCode(financeSubject.getGoodCategoryCode());
            invoiceDetailParamter.setIfDiscount(financeSubject.getIfDiscount().toString());
            invoiceDetailParamter.setTaxEspecialManager(financeSubject.getTaxEspecialManager());
            invoiceDetailParamter.setProjectName(financeSubject.getInvoiceProject());
            invoiceDetailParamter.setProjectNum(projectNum);
            invoiceDetailParamter.setTaxLogo("1");
            invoiceDetailParamter.setProjectUnitPrice(amount.abs().doubleValue());
            invoiceDetailParamter.setProjectAmount(amount.doubleValue());
            invoiceParamter.setInvoiceDetailParamterList(Arrays.asList(invoiceDetailParamter));
            Invoice invoice = new Invoice();
            BeanUtils.copyProperties(invoice, invoiceSaveVo);
            IEliWebServiceStub.ReturnElectronice haveElectronice = electronicInvoiceService.findInvoiceDetail(invoiceParamter);
            if (haveElectronice!=null && haveElectronice.getReturnCode().equals("0000") || haveElectronice.getReturnCode().equals("0")) {
                this.fillInvoice(invoice,haveElectronice);
            }else {
                IEliWebServiceStub.ReturnElectronice returnElectronice = electronicInvoiceService.makeOut(invoiceParamter);
                if (returnElectronice.getReturnCode().equals("0000") || returnElectronice.getReturnCode().equals("0")) {
                    this.fillInvoice(invoice,returnElectronice);

                } else {
                    String errMessage = "错误编码：" + returnElectronice.getReturnCode() + "," + returnElectronice.getReturnMsg();
                    throw new BusException(errMessage);
                }
            }

            dataSourceTransactionManager.commit(status);
            return invoice;
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(status);
            throw new BusException(e.getMessage());
        }

    }

    private void fillInvoice(Invoice invoice, IEliWebServiceStub.ReturnElectronice returnElectronice) {
        Principals.Principal principals=Principals.get();
        if (principals==null){
            principals=Principals.getDefaultPrincipal();
        }
        String returnMessage = JSONObject.toJSONString(returnElectronice);
        invoice.setReturnMessage(returnMessage);
        invoice.setStatus(1);/*有效*/
        invoice.setUpdateTime(TimeUtils.now());
        invoice.setCreateTime(TimeUtils.now());
        invoice.setPdfUrl(returnElectronice.getPDF_URL());
        invoice.setInvoiceCode(returnElectronice.getFP_DM());
        invoice.setInvoiceNumber(returnElectronice.getFP_HM());
        invoice.setInvoiceId(invoice.getInvoiceId());
        invoice.setCheckCode(returnElectronice.getJYM());

        invoice.setOperatorId(principals.id);
        invoice.setOperatorName(principals.name);
        this.insert(invoice);
        RecordTempInvoice recordTempInvoice = new RecordTempInvoice();
        recordTempInvoice.setRecordTempInvoiceId(invoice.getInvoiceId());
        recordTempInvoice.setStatus(0);
        recordTempInvoiceService.updateSelectiveById(recordTempInvoice);
        //为您开具的电子发票代码：144000930000，号码：10757285，开票日期：2017-12-11，校验码：82044899991209585143
        if (StringUtils.isNotEmpty(invoice.getBuyerEmail())) {

            final String content = "为您开具的电子发票代码：" + invoice.getInvoiceCode() + "," +
                    "号码:" + invoice.getInvoiceNumber() + ",开票日期:"+TimeUtils.date2String(TimeUtils.now(),"yyyy-MM-dd")+",校验码:" + returnElectronice.getJYM();
            final String toEmail = invoice.getBuyerEmail();
            String pdfUrl = returnElectronice.getPDF_URL();
            final List<String> urlString = Arrays.asList(pdfUrl);
            final String pdfName = pdfUrl.substring(pdfUrl.indexOf("=") + 1, pdfUrl.length());
            Threads.delay(new Runnable() {
                @Override
                public void run() {
                    emailService.sendEmail(toEmail, "广州誉优信息科技有限公司-电子发票信息", content, urlString, Arrays.asList(pdfName));
                }
            }, 20);
        }
    }



    private void sendEmail(Invoice invoice){
        if (StringUtils.isNotEmpty(invoice.getBuyerEmail())){
            final  String content="为您开具的电子发票代码："+invoice.getInvoiceCode()+","+
                    "号码:"+invoice.getInvoiceNumber()+",开票日期:"+TimeUtils.date2String(invoice.getCreateTime(),"yyyy-MM-dd")+",校验码:"+invoice.getCheckCode();
            final String toEmail=invoice.getBuyerEmail();
            String pdfUrl=invoice.getPdfUrl();
            final List<String> urlString=Arrays.asList(pdfUrl);
            final String pdfName=pdfUrl.substring(pdfUrl.indexOf("=")+1,pdfUrl.length());
            Threads.delay(new Runnable() {
                @Override
                public void run() {
                    emailService.sendEmail(toEmail,"广州誉优信息科技有限公司-电子发票信息",content,urlString,Arrays.asList(pdfName));
                }
            },3);
        }
    }


    @Override
    public void dealStudentRefund(Long regId) throws RemoteException {
        StudentReg studentReg=studentRegService.findById(regId);
        Long orderId=studentReg.getCourseOrderId();
        String orderType="courseOrderId";
        Invoice invoice=InvoiceServiceImpl.this.findByOrderIdAndStatus(orderId,1,1);
        if (invoice==null){
            orderId=regId;
            orderType="regId";
            invoice=InvoiceServiceImpl.this.findByOrderIdAndStatus(orderId,1,1);
        }
        InvoiceSaveVo rushOrOpenVo=null;
        if (invoice!=null){
            rushOrOpenVo=InvoiceServiceImpl.this.rushInvoice(invoice.getInvoiceId());
            rushOrOpenVo.setRushRedReason("退费");

            Invoice rushInvoice=InvoiceServiceImpl.this.saveOrRushInvoice(rushOrOpenVo);
            try{
                InvoiceSaveVo openVo=InvoiceServiceImpl.this.openInvoice(orderId,1,orderType);
                BeanUtils.copyProperties(rushOrOpenVo,openVo);
                rushOrOpenVo.setBuyerPhone(invoice.getBuyerPhone());
                rushOrOpenVo.setBuyerEmail(invoice.getBuyerEmail());
                rushOrOpenVo.setRemark(invoice.getRemark());
                Invoice openInvoice=InvoiceServiceImpl.this.saveOrRushInvoice(rushOrOpenVo);
            }catch (Exception e){

            }
        }


    }

    @Override
    public void sendInvoiceEmail(Long invoiceId) {
        Invoice invoice=this.findById(invoiceId);
        this.sendEmail(invoice);
    }

    @Override
    public void changeAndSendEmail(InvoiceSaveVo invoiceSaveVo) {
        if (invoiceSaveVo.getInvoiceId()==null){
            throw new BusException("id必传");
        }
        Invoice invoice=new Invoice();
        BeanUtils.copyProperties(invoice,invoiceSaveVo);
        Principals.Principal principal=Principals.get();
        invoice.setOperatorId(principal.id);
        invoice.setOperatorName(principal.name);
        invoice.setUpdateTime(TimeUtils.now());
        this.updateSelectiveById(invoice);
        this.sendInvoiceEmail(invoice.getInvoiceId());
    }
}